package video.plugin.app.qukeduo.qingclass.qkd_audio_recorder

import android.app.Activity
import android.media.AudioFormat
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.widget.Toast
import androidx.annotation.NonNull;
import com.czt.mp3recorder.MP3Recorder
//import com.zlw.main.recorderlib.RecordManager
//import com.zlw.main.recorderlib.recorder.RecordConfig
//import com.zlw.main.recorderlib.recorder.RecordHelper
//import com.zlw.main.recorderlib.recorder.listener.RecordStateListener
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
import java.io.File
import java.util.*

/** QkdAudioRecorderPlugin */
public class QkdAudioRecorderPlugin: FlutterPlugin, MethodCallHandler ,ActivityAware{

  private val tagQaPlugin="tagQaPlugin"

  private var mp3Recorder : MP3Recorder?= null
  private var outPutFilePath : String =""

  private var activity : Activity? = null
  private var timer : Timer? =null
  private var timerTask : TimerTask? =null

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "qkd_audio_recorder")
    channel?.setMethodCallHandler(this)
  }

  // This static function is optional and equivalent to onAttachedToEngine. It supports the old
  // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
  // plugin registration via this function while apps migrate to use the new Android APIs
  // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
  //
  // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
  // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
  // depending on the user's project. onAttachedToEngine or registerWith must both be defined
  // in the same class.
  companion object {

    var channel:MethodChannel?=null

    @JvmStatic
    fun registerWith(registrar: Registrar) {
      channel = MethodChannel(registrar.messenger(), "qkd_audio_recorder")
      channel?.setMethodCallHandler(QkdAudioRecorderPlugin())
    }
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    }else if(call.method=="stop"){
      Log.i(tagQaPlugin,"stop recorder")
      stopRecord2(true)
      stopVolumeTask()
      result.success(null)
    }else if(call.method=="start"){
      Log.i(tagQaPlugin,"start recorder")
      outPutFilePath = ""
      startRecord2()
      startVolumeTask()
      result.success(outPutFilePath)
    }else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
  }


  override fun onDetachedFromActivity() {
//    RecordManager.getInstance().stop()
    activity = null
    stopRecord2(false)
    stopVolumeTask()
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {

  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    activity = binding.activity
    //初始化recorder
//    RecordManager.getInstance().init(binding.activity.application, true)
  }

  override fun onDetachedFromActivityForConfigChanges() {
//    stopRecord2()
//    stopVolumeTask()
  }

  /**
   * 开始录音
   */
  private fun startRecord2(){

    stopRecord2(false)
    Log.i(tagQaPlugin,"startRecord2 mainThread = ${ThreadUtils.isMainThread()}")

    val outputDir = getOutputFile()
    if (null == outputDir){
      activity?.let {
        Toast.makeText(it,"获取音频录制输出路径失败",Toast.LENGTH_SHORT).show()
      }
    }

    File(outputDir, UUID.randomUUID().toString() + ".mp3").let {
      outPutFilePath = it.absolutePath
      mp3Recorder = MP3Recorder(it)
    }

    mp3Recorder?.let {

      it.setErrorHandler(object :Handler(){
        override fun handleMessage(msg: Message?) {
          super.handleMessage(msg)
          Log.i(tagQaPlugin,"record error = ${msg?.what}")
          when(msg?.what){
            MP3Recorder.ERROR_TYPE -> {
              Toast.makeText(activity, "没有麦克风权限", Toast.LENGTH_SHORT).show()
            }
          }
        }
      })

      it.start()
    }
  }

  /**
   * 停止录音
   */
  private fun stopRecord2(notify : Boolean){

    Log.i(tagQaPlugin,"stopRecord2  mainThread = ${ThreadUtils.isMainThread()}")

    mp3Recorder?.let {
      it.stop()
    }

    if (notify){
      channel?.invokeMethod("onRecordComplete",outPutFilePath)
    }

    mp3Recorder = null
    Log.i(tagQaPlugin,"stopRecord2 mp3Recorder = $mp3Recorder")

    Log.i(tagQaPlugin,"stopRecord2 suc")
  }

  private val mainHanlder = object :Handler(Looper.getMainLooper()){
    override fun handleMessage(msg: Message?) {
      super.handleMessage(msg)

      if (timer == null || timerTask == null || mp3Recorder == null){
        return
      }

      when(msg?.what){
        110 -> {
          Log.i(tagQaPlugin , "volume = ${msg.obj}")
          channel?.invokeMethod("onRecordSound",msg?.obj ?:0)
        }
      }
    }
  }

  private fun startVolumeTask(){
    stopVolumeTask()

    Log.i(tagQaPlugin,"startVolumeTask")

    timerTask = object : TimerTask() {
      override fun run() {
        Log.i(tagQaPlugin, "mp3Recorder = $mp3Recorder")
        if (null != mp3Recorder){
          val volume=mp3Recorder?.realVolume ?:0
          mainHanlder.obtainMessage(110, (volume/30).toInt()).sendToTarget()
        }
      }
    }

    timer =Timer()

    timer?.schedule(timerTask, 0, 100)
  }

  private fun stopVolumeTask(){
    Log.i(tagQaPlugin,"stopVolumeTask")
    timerTask?.let {
      it.cancel()
    }
    timer?.let {
      it.cancel()
    }
    timerTask = null
    timer = null
    mainHanlder.removeCallbacksAndMessages(null)
    Log.i(tagQaPlugin,"stopVolumeTask suc")
  }


//  private fun stopRecord1(){
//    RecordManager.getInstance().apply {
//      stop()
//    }
//  }


  /**
   * 获取输出路径
   */
  private fun getOutputFile() : File?{

    var dirPath = StringBuilder()
    val dirName = "audio"
    if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
      if (null == activity){
        dirPath.append(Environment.getExternalStorageDirectory().absolutePath)
                .append(File.separator)
                .append("qukeduo")
                .append(File.separator)
                .append(dirName)
      }else {

        val externalCacheDir = activity?.externalCacheDir
        val isExtendCacheExist = null!= externalCacheDir && externalCacheDir.exists()

        if (isExtendCacheExist){
          dirPath.append(externalCacheDir?.absolutePath).append(File.separator).append(dirName)
        }else {
          dirPath.append(activity?.cacheDir).append(File.separator).append(dirName)
        }
      }
    } else {
      if (null == activity){
        dirPath.append(Environment.getExternalStorageDirectory().absolutePath)
                .append(File.separator)
                .append("qukeduo")
                .append(File.separator)
                .append(dirName)
      }else {
        dirPath.append(activity?.cacheDir).append(File.separator).append(dirName)
      }
    }

    Log.i(tagQaPlugin , "getOutputFile dirPath= $dirPath")

    val dirFile = File(dirPath.toString())
    if (!dirFile.exists()){
      if (dirFile.mkdirs()){
        return dirFile
      }else{
        Log.i(tagQaPlugin , "getOutputFile 文件不存在")
        return null
      }
    }else{
      return dirFile
    }
  }


//  private fun startRecord1(){
//    RecordManager.getInstance().apply {
//      //音频格式
//      changeFormat(RecordConfig.RecordFormat.MP3)
//      //采样率
//      changeRecordConfig(recordConfig.setSampleRate(16000))
//      changeRecordConfig(recordConfig.setEncodingConfig(
//              AudioFormat.ENCODING_PCM_16BIT))
//
//      Log.i(tagQaPlugin,"$recordConfig")
//
//      //录制结果回调
//      setRecordResultListener {
//        Log.i(tagQaPlugin,"record result=${it.absolutePath}")
//        channel?.apply {
//          invokeMethod("onRecordComplete",it.absolutePath)
//        }
//      }
//
//      //录制音量回调
//      setRecordSoundSizeListener {
//        ThreadUtils.logIsMainThread()
//        Log.i(tagQaPlugin,"record sound =$it")
//        channel?.apply {
//          invokeMethod("onRecordSound",it)
//        }
//      }
//
//      start()
//    }
//  }
}

private fun MP3Recorder.setErrorHandler(any: Any) {

}
